#include "stm32.h"


// 客户端线程参数结构体
typedef struct
{
    int client_socket;
    char client_ip[INET_ADDRSTRLEN];
    int client_port;
    void *node_p;
    int *total;
    struct std_node *node_arr;
} ClientThreadArgs;

// 全局变量
int server_socket;
pthread_mutex_t data_mutex = PTHREAD_MUTEX_INITIALIZER;

// 控制线程函数
void *md_control(void *arg)
{
    int client_socket = *(int *)arg;
    struct msgbuf recv_buf;

    while (1)
    {
        // 从消息队列读取控制指令，然后执行对应的操作
        if (msg_queue_recv("topic", &recv_buf, sizeof(recv_buf), 0, 0) > 0)
        {
            printf("Received control command: %s\n", recv_buf.mdata);
            printf("Received control command: %ld\n", recv_buf.mtype);
            if (recv_buf.mtype == 1)
            {
                if (strcmp(recv_buf.mdata, "FAN_ON") == 0) // 正常开灯
                {
                    if (send(client_socket, "FAN_ON", strlen("FAN_ON"), 0) < 0)
                    {
                        perror("send error:");
                        // 修改：不再直接返回，而是继续监听
                        continue;
                    }
                    else
                    {
                        printf("-----------------------------------------------\n");
                        printf("-----------------搅拌设备已开启！-----------------\n");
                        printf("-----------------------------------------------\n");
                    }
                }
                else if (strcmp(recv_buf.mdata, "FAN_OFF") == 0) // 正常关灯
                {
                    if (send(client_socket, "FAN_OFF", strlen("FAN_OFF"), 0) < 0)
                    {
                        perror("send error:");
                        // 修改：不再直接返回，而是继续监听
                        continue;
                    }
                    else
                    {
                        printf("-----------------------------------------------\n");
                        printf("-----------------搅拌设备已关闭！-----------------\n");
                        printf("-----------------------------------------------\n");
                    }
                }
                if (strcmp(recv_buf.mdata, "BUZZ_ON") == 0) // 正常开灯
                {
                    if (send(client_socket, "BUZZ_ON", strlen("BUZZ_ON"), 0) < 0)
                    {
                        perror("send error:");
                        // 修改：不再直接返回，而是继续监听
                        continue;
                    }
                    else
                    {
                        printf("-----------------------------------------------\n");
                        printf("-----------------警报已开启！-----------------\n");
                        printf("-----------------------------------------------\n");
                    }
                }
                else if (strcmp(recv_buf.mdata, "BUZZ_OFF") == 0) // 正常关灯
                {
                    if (send(client_socket, "BUZZ_OFF", strlen("BUZZ_OFF"), 0) < 0)
                    {
                        perror("send error:");
                        // 修改：不再直接返回，而是继续监听
                        continue;
                    }
                    else
                    {
                        printf("-----------------------------------------------\n");
                        printf("-----------------已关闭！-----------------\n");
                        printf("-----------------------------------------------\n");
                    }
                }
            }
        }
        else
        {
            perror("recv error:");
            // 修改：不再直接返回，而是继续监听
            continue;
        }
    }
    return NULL;
}

// 处理 JSON 的线程函数
void *handle_json(void *arg)
{
    ClientThreadArgs *args = (ClientThreadArgs *)arg;
    char *json_data = (char *)args->node_p;
    int *total = args->total;
    struct std_node *node_arr = args->node_arr;

    // 加锁保护共享资源
    pthread_mutex_lock(&data_mutex);

    // 解析 JSON 数据
    cJSON *root = cJSON_Parse(json_data);
    if (root == NULL)
    {
        printf("单片机复位,JONS发生丢失\n");
        pthread_mutex_unlock(&data_mutex);
        free(json_data); // 释放内存
        return NULL;
    }

    cJSON *data = cJSON_GetObjectItem(root, "data");
    *total = total_num;

    // 处理数据项
    for (int i = 0; i < stm32_num && i < cJSON_GetArraySize(data); i++)
    {
        cJSON *item = cJSON_GetArrayItem(data, i);
        if (!item)
            continue;

        const char *name = cJSON_GetObjectItem(item, "name")->valuestring;
        double value = cJSON_GetObjectItem(item, "value")->valuedouble;

        node_arr[i].key = 301 + i;
        node_arr[i].type = stm32_arr[i].type;
        node_arr[i].dev_type = 1;
        node_arr[i].old_val.f_val = Past;
        Past = value;
        node_arr[i].new_val.f_val = Past;
        node_arr[i].ret = 0;

        printf("解析数据: name=%s, value=%.2lf\n", name, Past);
    }

    cJSON_Delete(root);
    pthread_mutex_unlock(&data_mutex);
    free(json_data); // 释放分配的内存
    return NULL;
}

// void JSON_parse()
// {
//     // 从node.json文件中读取JSON数据
//     FILE *fp = fopen("node.json", "r");
//     if (fp == NULL)
//     {
//         printf("无法打开文件\n");
//         return;
//     }

//     // 读取文件内容到字符串
//     fseek(fp, 0, SEEK_END);
//     long fsize = ftell(fp);
//     fseek(fp, 0, SEEK_SET);

//     char *json_str = (char *)malloc(fsize + 1);
//     if (!json_str)
//     {
//         printf("内存分配失败\n");
//         fclose(fp);
//         return;
//     }

//     fread(json_str, 1, fsize, fp);
//     fclose(fp);
//     json_str[fsize] = '\0'; // 添加字符串结束符

//     // 解析JSON数据
//     cJSON *root = cJSON_Parse(json_str);
//     if (root == NULL)
//     {
//         printf("解析JSON数据失败\n");
//         free(json_str);
//         return;
//     }

//     // 获取节点数组
//     cJSON *stm32 = cJSON_GetObjectItem(root, "stm32");
//     cJSON *data = cJSON_GetObjectItem(stm32, "data");
//     //获取modbus节点个数
//     total_num = cJSON_GetArraySize(data);   

    
//     // 遍历节点数组
//     int arr_size = cJSON_GetArraySize(data);
//     stm32_arr = (struct std_node *)malloc(arr_size * sizeof(struct std_node));

//     for (int i = 0; i < arr_size; i++)
//     {
//         cJSON *item = cJSON_GetArrayItem(data, i);
//         stm32_arr[i].key = cJSON_GetObjectItem(item, "key")->valueint;
//         stm32_arr[i].type = cJSON_GetObjectItem(item, "type")->valueint;
//     }

//     // 释放内存
//     cJSON_Delete(root);
//     free(json_str);
// }

// 处理客户端连接的线程函数
void *handle_client(void *arg)
{
    ClientThreadArgs *args = (ClientThreadArgs *)arg;
    int client_socket = args->client_socket;
    char *client_ip = args->client_ip;
    int client_port = args->client_port;

    printf("[服务器] 客户端 %s:%d 已连接\n", client_ip, client_port);

    // 初始化共享内存 - 移至main函数，避免重复初始化
    void *node_p = args->node_p;
    int *total = args->total;
    struct std_node *node_arr = args->node_arr;

    char buf[BUFFER_SIZE];

    // 创建控制线程
    pthread_t md_tid;
    pthread_create(&md_tid, NULL, md_control, &client_socket);
    pthread_detach(md_tid);

    while (1)
    {
        memset(buf, 0, BUFFER_SIZE);
        int ret = recv(client_socket, buf, sizeof(buf), 0);

        if (ret <= 0)
        {
            printf("[服务器] 客户端 %s:%d 已断开连接\n", client_ip, client_port);
            break;
        }

        // 打印接收到的数据
        printf("[来自 %s:%d] %s\n", client_ip, client_port, buf);

        // 分配内存存储 JSON 数据副本
        char *json_copy = (char *)malloc(ret + 1);
        if (!json_copy)
        {
            printf("内存分配失败，跳过当前消息\n");
            continue;
        }

        strcpy(json_copy, buf);

        // 创建线程处理 JSON
        args->node_p = json_copy;
        pthread_t json_tid;
        pthread_create(&json_tid, NULL, handle_json, args);
        pthread_detach(json_tid);
    }

    close(client_socket);
    free(args);
    return NULL;
}
void JSON_config()
{
    // 从config.json文件中读取JSON数据
    FILE *fp = fopen("config.json", "r");
    if (fp == NULL)
    {
        printf("无法打开文件\n");
        return;
    }
    // 读取文件内容到字符串
    fseek(fp, 0, SEEK_END);
    long fsize = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    char *json_str = (char *)malloc(fsize + 1);
    if (!json_str)
    {
        printf("内存分配失败\n");
        fclose(fp);
        return;
    }
    fread(json_str, 1, fsize, fp);
    fclose(fp);
    json_str[fsize] = '\0'; // 添加字符串结束符
    // 解析JSON数据
    cJSON *root = cJSON_Parse(json_str);
    if (root == NULL)
    {
        printf("解析JSON数据失败\n");
        free(json_str);
        return;
    }
         // 获取节点数组
    cJSON *stm32 = cJSON_GetObjectItem(root, "stm32");
    cJSON *data = cJSON_GetObjectItem(stm32, "data");
    //获取modbus节点个数
      cJSON *modbus = cJSON_GetObjectItem(root, "modbus");
    cJSON *data1 = cJSON_GetObjectItem(modbus, "data");
    //获取两个节点总和
     stm32_num= cJSON_GetArraySize(data);
    modbus_num = cJSON_GetArraySize(data1);
    total_num = modbus_num + stm32_num;
//打印三个节点个数
    printf("modbus_num = %d\n", modbus_num);
    printf("stm32_num = %d\n", stm32_num);
    printf("total_num = %d\n", total_num);
    
    // 遍历节点数组
    int arr_size = cJSON_GetArraySize(data);
    stm32_arr = (struct std_node *)malloc(arr_size * sizeof(struct std_node));

    for (int i = 0; i < arr_size; i++)
    {
        cJSON *item = cJSON_GetArrayItem(data, i);
        stm32_arr[i].key = cJSON_GetObjectItem(item, "key")->valueint;
        stm32_arr[i].type = cJSON_GetObjectItem(item, "type")->valueint;
    }


        // 解析出mqtt_server的addr和port
        cJSON *mqtt_server = cJSON_GetObjectItem(root, "mqtt_server");
       strcpy(IP, cJSON_GetObjectItem(mqtt_server, "addr")->valuestring);
       //在IP后面添加\0
        for (int i = 0; i < strlen(IP); i++)
        {
            if (IP[i] == ',')
            {
                IP[i] = '\0';
                break;
            }
        }
        PORT = cJSON_GetObjectItem(mqtt_server, "port")->valueint;
        // 释放内存
      cJSON_Delete(root);
    free(json_str);
}

int main()
{
    JSON_config();
    //JSON_parse();

    // 初始化共享内存（仅一次）
    int shmid = shm_init(&para, "shm_test", 1024);
    if (shmid < 0)
    {
        perror("shm_init err");
        return -1;
    }

    // 获取共享内存地址
    void *node_p = shm_getaddr(&para);
    if (node_p == NULL)
    {
        perror("shm_getaddr err");
        return -1;
    }

    int *total = (int *)node_p;
    struct std_node *node_arr = (struct std_node *)(node_p + sizeof(int));

    struct sockaddr_in server_addr, client_addr;
    socklen_t addr_len = sizeof(client_addr);

    // 创建套接字
    server_socket = socket(AF_INET, SOCK_STREAM, 0);

    // 设置地址重用
    int opt = 1;
    setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    // 绑定地址和端口
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(IP);
    server_addr.sin_port = htons(PORT);

    bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr));
    listen(server_socket, 5);

    printf("[服务器] 已启动，监听地址: %s:%d\n",
           inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port));

    // 主循环：接受客户端连接并创建线程
    while (1)
    {
        int client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &addr_len);

        ClientThreadArgs *args = (ClientThreadArgs *)malloc(sizeof(ClientThreadArgs));
        if (!args)
        {
            perror("内存分配失败");
            close(client_socket);
            continue;
        }

        args->client_socket = client_socket;
        inet_ntop(AF_INET, &client_addr.sin_addr, args->client_ip, INET_ADDRSTRLEN);
        args->client_port = ntohs(client_addr.sin_port);
        args->node_p = node_p;
        args->total = total;
        args->node_arr = node_arr;

        pthread_t tid;
        pthread_create(&tid, NULL, handle_client, args);
        pthread_detach(tid);
    }

    // 清理资源
    shmdt(node_p);
    shmctl(shmid, IPC_RMID, NULL);
    if (stm32_arr)
        free(stm32_arr);
    close(server_socket);
    return 0;
}